package com.nbot.server;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.log.StaticLog;
import com.alibaba.fastjson.JSON;
import com.nbot.common.InterpreterFactory;
import com.nbot.common.command.BaseCommand;
import com.nbot.common.command.BotCommand;
import com.nbot.serial.ContinueRead;
import com.nbot.server.domain.Commandlog;
import com.nbot.server.properties.NbotProperties;
import com.nbot.server.service.CommandlogService;
import com.nbot.server.util.SpringUtil;
import com.nbot.server.workers.DbWorker;
import com.nbot.server.workers.OpcWorker;
import org.jinterop.dcom.common.JIException;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class BotServer {

    public static final int PORT = 8000;//监听的端口号
    public static PriorityBlockingQueue<BotCommand> comandQueue = new PriorityBlockingQueue<BotCommand>(10000);
    public static LinkedBlockingQueue<byte[]> uartQueue = new LinkedBlockingQueue<byte[]>(10000);
    private static final Log log = LogFactory.get();


    @Autowired
    private NbotProperties nbotProperties;
    @Autowired
    private CommandlogService commandlogService;



    public static BotCommand getCommand() {
        return comandQueue.poll();
    }

    public static void putCommand(BotCommand command) {
/*
        CommandlogService commandlogService = (CommandlogService) SpringUtil.getBean("commandlogService");
        Commandlog commandlog =new Commandlog();
        //d.setKey(new Date().toString());
        commandlog.setCommandName(command.getClass().getSimpleName());
        commandlog.setDate(new Date());
        commandlog.setCommandValue(command.toString());
        //d.setValue();
        commandlogService.insert(commandlog);
        */
        comandQueue.add(command);
    }


    public void addCommand(BotCommand command) {

        //CommandlogService commandlogService = (CommandlogService) SpringUtil.getBean("commandlogService");
        Commandlog commandlog = new Commandlog();
        //d.setKey(new Date().toString());
        commandlog.setCommandname(command.getClass().getSimpleName());
        commandlog.setDate(new Date());
        commandlog.setCommandvalue(command.toString());
        //d.setValue();
        commandlogService.insert(commandlog);

        comandQueue.add(command);
    }

    public static void addUartMsg(BotCommand command) throws UnsupportedEncodingException {
        String sendStr= JSON.toJSONString(command) + "@" + command.getClass().getName();
        byte[] sendData= new byte[sendStr.getBytes("unicode").length+4];
        sendData[0] = (byte) 0xFD;
        sendData[1] = (byte) 0xCA;
        System.arraycopy(sendStr.getBytes("unicode"),0,sendData,2,sendStr.getBytes("unicode").length);
        sendData[sendStr.getBytes("unicode").length+2] = (byte) 0xFF;
        sendData[sendStr.getBytes("unicode").length+3] = (byte) 0xEE;
        uartQueue.add(sendData);
    }

    public static byte[] getUartMsg() {
        return uartQueue.poll();
    }

    public static void main(String[] args) {
        //这个线程模拟server向消息队列发送消息（指令）
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                OpcWorker opcWorker = (OpcWorker) SpringUtil.getBean("opcWorker");
//                for (int i = 0; i < 100; i++) {
//                    try {
//                        opcWorker.readData(i + "");
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//
//                    try {
//                        Thread.sleep(new Random().nextInt(1000));
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//
//                }
//            }
//        }).start();
        BotServer server = new BotServer();
        //  server.init();
    }

    /**
     * server 初始化
     */
    public void init() {
        //报警开关
        boolean alarmSwitch = nbotProperties.getOpc().isOpcAlarm();
        log.info("Server start!!!");
        try {
//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    OpcWorker opcWorker = (OpcWorker) SpringUtil.getBean("opcWorker");
//                    while (alarmSwitch) {
//                        try {
////                            opcWorker.checkOilWell();//3厂油井 - Job
////                            opcWorker.checkWaterWell();//3厂水井 -job
////                            opcWorker.checkAllAnalogPoint();//  3厂生产
//                            opcWorker.checkRelevanceAlarm();//3厂产量 - Job
////                            opcWorker.checkAllPoint();//3厂油井状态 - Job
//                            Thread.sleep(1000);
//                        } catch (JIException e) {
//                            e.printStackTrace();
//                        } catch (UnknownHostException e) {
//                            e.printStackTrace();
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }).start();

            new Thread(new Runnable() { //add wyzc 重点督办check线程
                @Override
                public void run() {
                    DbWorker IECCheckDbWorker = (DbWorker) SpringUtil.getBean("dbWorker");//先写着，不懂
                    while (true) {
                        try {
                            IECCheckDbWorker.checkIEC();
                            IECCheckDbWorker.checkLogTrans();
                            Thread.sleep(60000);
                        } catch (JIException e) {
                            e.printStackTrace();
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();

//            new Thread(new Runnable() {
//                @Override
//                public void run() {
//                    int mins = Integer.parseInt(nbotProperties.getOracleAlarmInterval());
//                    while (nbotProperties.isOracleAlarm()) {
//
//                        oracleWorker.checkAlarmLog();
//                        oracleWorker.checkAqyhLog();
//                        oracleWorker.checkFxglLog();
//                        oracleWorker.checkAqyhOldLog();
//                        try {
//                            Thread.sleep(mins * 60 * 1000);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }).start();

            ContinueRead cRead = new ContinueRead();
            cRead.startComPort();
            cRead.start();
            new Thread(new Runnable() { //add wyzc 重点督办check线程
                @Override
                public void run() {
                    while (true) {
                       byte[] command = BotServer.getUartMsg();
                       if (command != null) {
                           cRead.sendMsg(command);
                           try {
                               StaticLog.info("发送："+new String(command,"unicode"));
                           } catch (UnsupportedEncodingException e) {
                               e.printStackTrace();
                           }
                       }
                    }
                }
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

/*
 *处理读操作的线程
 */
//class ServerReadHandlerThread implements Runnable {
//    private Socket client;
//    private static final Log log = LogFactory.get();
//
//    public ServerReadHandlerThread(Socket client) {
//        log.info("new 了一个 ServerReadHandlerThread");
//        this.client = client;
//    }
//
//    @Override
//    public void run() {
//        ObjectInputStream dis = null;
//        try {
//            while (true) {
//                dis = new ObjectInputStream(client.getInputStream());
//                BaseCommand receiveCommand = (BaseCommand) dis.readObject();
//                log.info("server接收到bot的一个指令[" + receiveCommand.getClass().getSimpleName() + "]: " + receiveCommand);
//                InterpreterFactory.getInterpreter(receiveCommand).execute();
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                if (dis != null) {
//                    dis.close();
//                }
//                if (client != null) {
//                    client = null;
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//}

/*
 * 处理写操作的线程
 */
//class ServerWriteHandlerThread implements Runnable {
//    private Socket client;
//
//    private static final Log log = LogFactory.get();
//
//    public ServerWriteHandlerThread(Socket client) {
//        log.info("new 了一个 ServerWriteHandlerThread");
//        this.client = client;
//    }
//
//    @Override
//    public void run() {
//        ObjectOutputStream dos = null;
//
//        try {
//            while (true) {
//                BotCommand command = BotServer.getCommand();
//                if (command != null) {
//
//                    // Thread.sleep(new Random().nextInt(1000));
//                    dos = new ObjectOutputStream(client.getOutputStream());
//                    log.info("server向bot发送一个指令[" + command.getClass().getSimpleName() + "]:" + command);
//                    log.info("当前Server队列长度为" + BotServer.comandQueue.size());
//                    log.info("当前Server队列长度为" + BotServer.comandQueue.size());
//                    dos.writeObject(command);
//                }
//
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                if (dos != null) {
//                    dos.close();
//                }
//                if (client != null) {
//                    client = null;
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//}